﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common.UI.EM.Views.Interfaces;
using Common.UI.EM.Views;
using Common.Model;
using Common.Services;
using System.Data.Objects.DataClasses;

namespace Common.UI.EM
{
    public class GenericController<S, E, C, EV>
        where S : IGenericEntityManagerService<E, C, EV>, new()
        where E : EntityObject, new()
        where C : CriteriaEntity, new()
        where EV : ViewEntity
    {
        public virtual String Titulo
        {
            get { return string.Empty; }
        }

        public IFilterPresentationModel<S, E, C, EV> FilterPresentationModel
        {
            get;
            set;
        }
        public IDetailPresentationModel<S, E, C, EV> DetailPresentationModel
        {
            get;
            set;
        }
        public IListPresentationModel<S, E, C, EV> ListPresentationModel
        {
            get;
            set;
        }

        public IEntityManagerView EntityManagerView
        {
            get;
            set;
        }

        public C LastCriteria { get; set; }

        public virtual void Run()
        {
            this.CreatePresentationModels();

            this.CreateEntityManagerView();

            this.RegisterEventHandlers();

            this.InitializePresentationModels();

            this.RegisterEntityManagerView();
        }

        public void RunInAdd()
        {
            this.Run();
            this.ShowDetail(DetailMode.Add, null);
        }
       
        private void CreatePresentationModels()
        {
            this.CreateFilterPresentationModel();
            this.CreateListPresentationModel();
            this.CreateDetailPresentationModel();
        }


        protected virtual void CreateFilterPresentationModel()
        {
            this.FilterPresentationModel = new FilterPresentationModel<S, E, C, EV>(this.CreateFilterView());
        }

        protected IFilterView CreateFilterView()
        {
            var dv = new FilterView();
            dv.ContentControl = this.CreateFilterDataView();
            return dv;
        }

        protected virtual FilterDataView CreateFilterDataView()
        {
            return new FilterDataView();
        }


        protected virtual void CreateDetailPresentationModel()
        {
            this.DetailPresentationModel = new DetailPresentationModel<S, E, C, EV>(this.CreateDetailView());
        }

        protected IDetailView CreateDetailView()
        {
            var dv = new DetailView();
            dv.ContentControl = this.CreateDetailDataView();
            return dv;
        }


        private void UpdateDetailDataView()
        {
            this.DetailPresentationModel.View.ContentControl = this.CreateDetailDataView();
        }

        protected virtual DetailDataView CreateDetailDataView()
        {
            return new DetailDataView();
        }


        protected virtual void CreateListPresentationModel()
        {
            this.ListPresentationModel = new ListPresentationModel<S, E, C, EV>(this.CreateListView());
        }

        protected ListView CreateListView()
        {
            return new ListView();
        }

        private void CreateEntityManagerView()
        {
            EntityManagerView = new EntityManagerView(this.FilterPresentationModel.View, this.ListPresentationModel.View, this.DetailPresentationModel.View);
        }

        private void RegisterEventHandlers()
        {
            this.FilterPresentationModel.SearchCalled += new SearchCalledEventHandler(FilterPresentationModel_SearchCalled);

            this.ListPresentationModel.AddCalled += new AddCalledEventHandler(ListPresentationModel_AddCalled);
            this.ListPresentationModel.ModifyCalled += new ModifyCalledEventHandler(ListPresentationModel_ModifyCalled);
            this.ListPresentationModel.ViewCalled += new ViewCalledEventHandler(ListPresentationModel_ViewCalled);
            this.ListPresentationModel.DeleteCalled += new DeleteCalledEventHandler(ListPresentationModel_DeleteCalled);

            this.DetailPresentationModel.SaveCalled += new SaveCalledEventHandler(DetailPresentationModel_SaveCalled);
            this.DetailPresentationModel.CancelCalled += new CancelCalledEventHandler(DetailPresentationModel_CancelCalled);

            this.RegisterCustomEventHandlers();
        }

        protected virtual void RegisterCustomEventHandlers()
        {
        }

        
        void FilterPresentationModel_SearchCalled(object sender, Microsoft.Practices.Composite.Events.DataEventArgs<CriteriaEntity> e)
        {
            EntityManagerView.ShowFilter();
            this.ListPresentationModel.LoadList(e.Value as C);
            LastCriteria = e.Value as C;
        }

        
        void ListPresentationModel_ViewCalled(object sender, Microsoft.Practices.Composite.Events.DataEventArgs<ViewEntity> e)
        {
            this.ShowDetail(DetailMode.View, e.Value);
        }

        void ListPresentationModel_ModifyCalled(object sender, Microsoft.Practices.Composite.Events.DataEventArgs<ViewEntity> e)
        {
            this.ShowDetail(DetailMode.Modify, e.Value);
        }

        void ListPresentationModel_DeleteCalled(object sender, Microsoft.Practices.Composite.Events.DataEventArgs<ViewEntity> e)
        {
            EntityManagerView.ShowFilter();
            if (LastCriteria != null)
            {
                this.ListPresentationModel.LoadList(this.LastCriteria as C);
            }
        }

        void ListPresentationModel_AddCalled(object sender, EventArgs e)
        {
            this.ShowDetail(DetailMode.Add, null);
        }


        private void ShowDetail(DetailMode detailMode, ViewEntity viewEntity)
        {
            
            UpdateDetailDataView();

            EntityManagerView.ShowDetail();
            if (detailMode != DetailMode.Add)
            {
                this.DetailPresentationModel.LoadEntity(viewEntity as EV);
            }
            else
            {
                this.DetailPresentationModel.LoadEntity(new E());
            }
            this.DetailPresentationModel.Mode = detailMode;
        }


        void DetailPresentationModel_CancelCalled(object sender, EventArgs e)
        {

            EntityManagerView.ShowList();
        }

        void DetailPresentationModel_SaveCalled(object sender, EventArgs e)
        {
            EntityManagerView.ShowFilter();
            if (LastCriteria != null)
            {
                this.ListPresentationModel.LoadList(this.LastCriteria as C);
            }
        }


        private void InitializePresentationModels()
        {
            this.FilterPresentationModel.LoadCriteria(new C());
            this.AddColumnDefinitions();
        }

        protected virtual void AddColumnDefinitions()
        {
        }


        private void RegisterEntityManagerView()
        {
            MainView.View.RegisterView(this.Titulo, this.EntityManagerView);
        }

    }
}
